#ifndef STATELISTENER_H
#define STATELISTENER_H


#include <string>


class State;




class StateListener
{
    public:
        StateListener(){};
        virtual ~StateListener(){};



    virtual void manageState(std::string stateName, State* state)=0;

	virtual State*	    findByName(std::string stateName) = 0;
	virtual void		changeState(State *state) = 0;
	virtual bool		pushState(State* state) = 0;
	virtual void		popState() = 0;
	virtual void		pauseState() = 0;
	virtual void		shutdown() = 0;
    virtual void        popAllAndPushState(State* state) = 0;



    protected:
    private:
};


class State
{
public:
	static void create(StateListener* parent, const std::string name){};

	void destroy(){delete this;}

	virtual void enter() = 0;
	virtual void exit() = 0;
	virtual bool pause(){return true;}
	virtual void resume(){};
	virtual void update(double timeSinceLastFrame) = 0;


protected:
	State(){};

	State*	    findByName(std::string stateName){return m_pParent->findByName(stateName);};
	void		changeState(State* state){m_pParent->changeState(state);};
	bool		pushState(State* state){return m_pParent->pushState(state);};
	void		popState(){m_pParent->popState();};
	void		shutdown(){m_pParent->shutdown();};
    void        popAllAndPushState(State* state){m_pParent->popAllAndPushState(state);};

	StateListener*	m_pParent;

};


#define DECLARE_STATE_CLASS(T)					\
static void create(AppStateListener* parent, const std::string name)	\
{									\
	T* myAppState = new T();					\
	myAppState->m_pParent = parent;					\
	parent->manageState(name, myAppState);			\
}

#endif // STATELISTENER_H
